home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1998 July / EnigmA AMIGA RUN 29 (1998)(G.R. Edizioni)(IT)[!][issue 1998-07 & 08].iso / earcd / utils / madhouse / developer / c / examples / water / water.c < prev    next >
C/C++ Source or Header  |  1997-12-21  |  9KB  |  516 lines

  1.  
  2. // Water.c
  3.  
  4. // Used as a demo for blanker programming.
  5. // Compiled with MaxonC++ 4 Dev.
  6.  
  7. // OS-Includes
  8.  
  9. #include <intuition/screens.h>
  10. #include <clib/graphics_protos.h>
  11. #include <clib/intuition_protos.h>
  12. #include <clib/dos_protos.h>
  13. #include <pragma/dos_lib.h>
  14. #include <pragma/exec_lib.h>
  15. #include <pragma/graphics_lib.h>
  16. #include <pragma/intuition_lib.h>
  17. #include <pragma/madblankersupport_lib.h>
  18.  
  19. #include <dos/dos.h>
  20. #include <intuition/intuition.h>
  21. #include <intuition/screens.h>
  22. #include <graphics/displayinfo.h>
  23. #include <graphics/gfxbase.h>
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <time.h>
  30.  
  31. #define NDEBUG 1
  32. #include <assert.h>
  33.  
  34.  
  35.  
  36. // Variablen
  37. struct Screen *scr = NULL;
  38. struct Window *win = NULL;
  39.  
  40. struct Library *IntuitionBase = NULL;
  41. struct Library *GfxBase = NULL;
  42. struct Library *madblankersupportbase = NULL;
  43.  
  44. struct RastPort *rast;
  45. struct ViewPort *view;
  46.  
  47. struct RastPort col[256];
  48. struct RastPort col0;
  49. UWORD col_anz;
  50.  
  51. UWORD BlPalette[] = {
  52.     0x0000,
  53.     0x0666,
  54.     0x0999,
  55.     0x0FFF
  56. };
  57.  
  58.  
  59. //ULONG ScrMode = 0x8000; // pAL highres
  60. //ULONG ScrMode = 0x99004; // dblNTSC flickerfixed.
  61. ULONG ScrMode = 0; // PAL lowres
  62. UWORD SWidth;
  63. UWORD SHeight;
  64. UWORD SWidth2;
  65. UWORD SHeight2;
  66. UWORD SWidth16;
  67. UWORD SHeight16;
  68. ULONG SDepth = 3;
  69.  
  70. short kanz = 10;
  71.  
  72.  
  73. UWORD xscale; // = 16;        // 16 entspricht 640 Pixeln
  74. UWORD yscale; // = 16;      // 16 entspricht 400 Pixeln
  75.  
  76.  
  77. UWORD maxx, maxy;
  78.  
  79.  
  80. const short yfact = 10;
  81.  
  82. BOOL OS3 = FALSE;
  83.  
  84.  
  85.  
  86.  
  87.  
  88. // Preferences
  89.  
  90. UWORD Drop_anz = 500;        // min. 20!
  91. UWORD Time = 15;
  92. UWORD bounce_type = 0;
  93. #define BT_NONE            0
  94. #define BT_BOTTOM        1
  95. #define BT_ONCE            2
  96. #define BT_TWO            3
  97.  
  98.  
  99. // Libs, Screen, Window
  100.  
  101. void close_blanker()
  102. {
  103.     if( win ) CloseWindow( win );
  104.     if( scr ) CloseScreen( scr );
  105.     scr = NULL;
  106.     if( GfxBase ) CloseLibrary( GfxBase );
  107.     if( IntuitionBase ) CloseLibrary( IntuitionBase );
  108. }
  109.  
  110. BOOL setup_blanker()
  111. {
  112.     IntuitionBase = OpenLibrary("intuition.library",37);
  113.     if( !IntuitionBase ) {
  114.         return FALSE;
  115.     }
  116.     GfxBase = OpenLibrary("graphics.library",37);
  117.     if( !GfxBase ) {
  118.         return FALSE;
  119.     }
  120.     
  121.     if( GfxBase->lib_Version >= 39 ) OS3 = TRUE;
  122.     
  123.     scr = OpenScreenTags(NULL,
  124.           SA_Depth,         SDepth,
  125.           SA_Interleaved,   FALSE,
  126.           SA_DisplayID,      ScrMode,
  127.           SA_Title,          "Water",
  128.           SA_Overscan,      OSCAN_STANDARD,
  129.           TAG_DONE);
  130.     
  131.     col_anz = 1 << SDepth;
  132.     
  133.     if( !scr ) {
  134.         MBS_ErrorReport( "Couldn't open Screen!" );
  135.         return FALSE;
  136.     }
  137.  
  138.     SWidth = scr->Width;
  139.     SHeight = scr->Height;
  140.     SWidth2 = SWidth / 2;
  141.     SHeight2 = SHeight / 2;
  142.     
  143.     xscale = 10240 / SWidth;
  144.     yscale = 6400 / SHeight;
  145.         
  146.     SWidth16 = SWidth * xscale;
  147.     SHeight16 = SHeight * yscale;
  148.     
  149.     view = &scr->ViewPort;
  150.     
  151.     SetRGB4( view,  0,  0,0,0 );
  152.  
  153.     win = OpenWindowTags(NULL,
  154.              WA_AutoAdjust,    TRUE,
  155.              WA_NoCareRefresh, TRUE,
  156.              WA_CustomScreen,  scr,
  157.              WA_Flags,         WFLG_RMBTRAP,
  158.              WA_Borderless,    TRUE,
  159.              WA_Activate,      TRUE,
  160.              TAG_DONE );
  161.     if( !win ) {
  162.         MBS_ErrorReport( "Couldn't open Window!");
  163.         return FALSE;
  164.     }
  165.     
  166.     MBS_ClearMousePointer( scr );
  167.     
  168.     rast = &(scr->RastPort);
  169.         
  170.     col0 = *win->RPort;
  171.     SetAPen( &col0, 0);
  172.     
  173.     maxx = 10240 - xscale*2 - 1;
  174.     for( UWORD y = 5000; y < 6400; y++ ) {
  175.         if( WritePixel( &col0, 0, y / yscale ))
  176.             break;
  177.     }
  178.     maxy = y;
  179.         
  180.     col[0] = *win->RPort;
  181.     SetAPen( &col[0], 0);
  182.     
  183.     for( short i=1; i<col_anz; i++) {
  184.         col[i] = *win->RPort;
  185.         SetAPen( &col[i], i);
  186.         if( OS3 ) {
  187.             SetRGB32( view, i,  i*255/col_anz << 24, i*255/col_anz << 24, 255 << 24);
  188.         } else {
  189.             SetRGB4( view, i,   i*15/col_anz, i*15/col_anz, 15 );
  190.         }
  191.     }
  192.     
  193.     return TRUE;
  194. }
  195.  
  196.  
  197.  
  198. UWORD maxsteps = 0;
  199.  
  200. WORD above_basestep, middle_basestep, below_basestep;
  201. WORD range_left, range_right;
  202.  
  203.  
  204. class GlobalInitValues
  205. {
  206.   public:
  207.     WORD xbase, xmaxadd,
  208.           ybase, ymaxadd,
  209.           xdirbase, xdirmaxadd,
  210.           ydirbase, ydirmaxadd;
  211.     
  212.     void Renew();
  213. };
  214.  
  215. void GlobalInitValues::Renew()
  216. {
  217.     xdirbase = Random(150)-75; //Random(100)-50;
  218.     xdirmaxadd = Random(40)+1;
  219.     xdirbase -= xdirmaxadd / 2;
  220.     
  221.     if( abs(xdirbase + xdirmaxadd) > 100 ) {
  222.         xdirbase /= 2;
  223.         xdirmaxadd /= 2;
  224.     }
  225.     
  226.     ydirbase = Random(100)-20-40;
  227.     ydirmaxadd = 3; //Random(5)-3;
  228.     
  229.     if( xdirbase > 0) {
  230.         xbase = Random(3000) + 900;
  231.         xmaxadd = Random(1000)+40; // Random(20);
  232.     } else {
  233.         xbase = Random(3000) + 6000;
  234.         xmaxadd = Random(1000)+40; // Random(20);    
  235.     }
  236.     
  237.     ybase = 300; // + (abs(ydirbase)+20)*10;
  238.     if( ydirbase < 0 ) {
  239.         ybase = 300 - ydirbase*30;
  240.     }
  241.     ymaxadd = 100; //Random(3);
  242.     
  243.     
  244.     if( Random(10) == 1 ) {
  245.         xdirbase /= 10;
  246.         xmaxadd = 2000 + Random(5000);
  247.         xbase = 1000;
  248.     }
  249.     
  250.     
  251.     // Hier gleich mit erledigt...
  252.     middle_basestep = 2000 + Random(2500);
  253.     above_basestep = 2000 + Random(700);
  254.     below_basestep = 2700 + Random(2800);
  255.     
  256.     
  257.     UWORD range_size = 2000 + Random( 7000 );
  258.     range_left = Random( 10240 - range_size );
  259.     range_right = range_left + range_size;
  260. }
  261.  
  262.  
  263.  
  264. class GlobalInitValues GIV;
  265.  
  266. class WaterDrop
  267. {
  268.   private:
  269.     WORD xpos, ypos;
  270.     WORD  xdir, ydir;
  271.     RastPort *col_used;
  272.     UWORD     col_num;
  273.     UWORD life;
  274.     UWORD bounce_cnt;
  275.     
  276.   public:
  277.     void GlobalInit();
  278.     inline void CalcMove();
  279.     
  280.     UWORD TestMove();
  281.     void ForwardMoves( UWORD steps );
  282.  
  283.     void Move();
  284.     
  285.     void Reset( WORD x, WORD y );
  286.     void SetDirection( WORD xd, WORD yd );
  287. };
  288.  
  289. void WaterDrop::GlobalInit()
  290. {
  291.     Reset( GIV.xbase + Random(GIV.xmaxadd), GIV.ybase+Random(GIV.ymaxadd) );
  292.     SetDirection( Random(GIV.xdirmaxadd)+GIV.xdirbase, Random(GIV.ydirmaxadd)+GIV.ydirbase );
  293.     //Reset( 1000+Random(140), 300+Random(50) );
  294.     //SetDirection( Random(20)+30, Random(5)+10 );
  295.     life = 0;
  296.     bounce_cnt = 0;
  297. }    
  298.  
  299.     
  300. inline void WaterDrop::CalcMove()
  301. {
  302.     xpos += xdir;
  303.     ypos += ydir++;
  304.     
  305.     BOOL flag = FALSE;
  306.     
  307.     switch( bounce_type ) {
  308.     // case BT_NONE:
  309.     //    break;
  310.         case BT_BOTTOM:
  311.             flag =   ypos > maxy && bounce_cnt < 2;
  312.             break;
  313.         case BT_ONCE:
  314.             flag =   (ypos > middle_basestep && bounce_cnt == 0 );
  315.             break;
  316.         case BT_TWO:
  317.             flag =    (ypos > above_basestep &&  xpos > range_left && xpos < range_right && bounce_cnt == 0)
  318.                   || (ypos > below_basestep && bounce_cnt < 2);
  319.            break;
  320.     }
  321.     
  322.     if( flag ) {
  323.         ydir = -( (ydir * 1) / 3 );
  324.         ydir -= Random(4);
  325.         ypos += ydir++;
  326.         
  327.         xdir /= 4;
  328.         xdir += Random(30)-15;
  329.         
  330.         bounce_cnt++;
  331.         
  332.         //if( ydir > -rebounce ) ypos = maxy+1000;
  333.     }
  334. }    
  335.  
  336.  
  337.  
  338. UWORD WaterDrop::TestMove()
  339. {
  340.     GlobalInit();
  341.     
  342.     for( UWORD cnt = 0; ; cnt++ ) {
  343.         CalcMove();
  344.         if( (ypos > maxy) || (xpos < 0) || (xpos >maxx) || (ypos < 0) )
  345.             return cnt;
  346.     }
  347. }
  348.  
  349.  
  350. void WaterDrop::ForwardMoves( UWORD steps )
  351. {
  352.     // ein kleiner Vorlauf, damit die Dinger sich verteilen lassen.
  353.     
  354.     GlobalInit();
  355.     
  356.     for( UWORD cnt = 0; cnt < steps; cnt++ ) {
  357.         CalcMove();
  358.         
  359.         life++;
  360.         if( life > (maxsteps / col_anz) ) {
  361.             life = 0;
  362.             if( col_num < col_anz - 1 )  col_num++;
  363.             col_used = &col[col_num];
  364.         }
  365.  
  366.         if( (ypos > maxy) || (xpos < 0) || (xpos >maxx) || (ypos < 0) )
  367.             GlobalInit();
  368.     }
  369. }
  370.  
  371.  
  372.  
  373. void WaterDrop::Move()
  374. {
  375.     WritePixel( &col0, xpos / xscale, ypos / yscale );
  376.     
  377.     CalcMove();
  378.     
  379.     life++;
  380.     if( life > (maxsteps / col_anz) ) {
  381.         life = 0;
  382.         if( col_num < col_anz - 1 )  col_num++;
  383.         col_used = &col[col_num];
  384.     }
  385.     
  386.     if( WritePixel( col_used, xpos / xscale, ypos / yscale ) == -1 ) {
  387.         GlobalInit();
  388.     }
  389. }
  390.  
  391.  
  392. void WaterDrop::Reset( WORD x, WORD y )
  393. {
  394.     WritePixel( &col0, xpos / xscale, ypos / yscale );
  395.     
  396.     xpos = x;
  397.     ypos = y;
  398.     
  399.     UWORD c = 1;
  400.     col_used = &col[c];
  401.     col_num = c;
  402. }
  403.  
  404.  
  405. void WaterDrop::SetDirection( WORD xd, WORD yd )
  406. {
  407.     xdir = xd;
  408.     ydir = yd;
  409. }
  410.  
  411.  
  412.  
  413.  
  414.  
  415. class WaterDrop *WD;
  416.  
  417.  
  418.  
  419. void DistributeWD()
  420. {
  421.     maxsteps = 0;
  422.     UWORD thisanz = 0;
  423.     
  424.     for( short n = 0; n < 20; n++ ) {
  425.         thisanz = WD[n].TestMove();
  426.         maxsteps += thisanz;
  427.         //if( thisanz > maxsteps ) maxsteps = thisanz;
  428.     }
  429.     
  430.     maxsteps /= 20;
  431.     
  432.     for( n = 0; n < Drop_anz; n++ ) {
  433.         WD[n].ForwardMoves( (maxsteps * n) / Drop_anz );
  434.     }
  435. }    
  436.  
  437.  
  438. // Hauptprogramm
  439.  
  440. void ende()
  441. {
  442.     close_blanker();
  443.     if( madblankersupportbase ) {
  444.         MBS_Quit();
  445.         CloseLibrary( madblankersupportbase );
  446.     }
  447.     exit( 0 );
  448. }
  449.  
  450. void main()
  451. {
  452.     BOOL quit = FALSE;
  453.     
  454.     madblankersupportbase = OpenLibrary(MADBLANKERSUPPORT_NAME,MADBLANKERSUPPORT_VMIN);
  455.     if( !madblankersupportbase ) exit(20);
  456.     
  457.     //MBS_DebugMode();
  458.     
  459.     if( !MBS_GetBlankjob() ) {
  460.         CloseLibrary( madblankersupportbase );
  461.         exit(20);
  462.     }
  463.         
  464.     
  465.     ScrMode = MBS_GetScreenmodePrefs( 0 /*0x99004*/ );
  466.     SDepth = MBS_GetScreendepthPrefs( 2 );
  467.     Drop_anz = MBS_GetPrefs( "drops", 400 );
  468.     Time = MBS_GetPrefs( "duration", 35 );
  469.     bounce_type = MBS_GetPrefs( "bouncetype", 1 );
  470.     
  471.     WD = new WaterDrop [ Drop_anz ];
  472.     if( ! WD ) {
  473.         MBS_Quit();
  474.         CloseLibrary( madblankersupportbase );
  475.         exit(0);
  476.     }
  477.         
  478.     if( setup_blanker() ) {
  479.         
  480.         UWORD cnt = 0;
  481.         BOOL conti = TRUE;
  482.         
  483.         time_t starttime;
  484.         
  485.         while( !MBS_ContinueBlanking() ) {
  486.             cnt = 0;
  487.             conti = TRUE;
  488.             RectFill( &col0, 0, 0, SWidth-1, SHeight-1 );
  489.             GIV.Renew();
  490.             DistributeWD();
  491.             starttime = time(NULL);
  492.             while( !MBS_ContinueBlanking() && conti ) {
  493.                 cnt++;
  494.                 if( cnt == 15 ) {
  495.                     cnt = 0;
  496.                     conti = (time(NULL) - starttime) < Time;
  497.                 }
  498.                 WaterDrop *cursor = &WD[0];
  499.                 for( short n = 0; n < Drop_anz; n++ ) {
  500.                     cursor->Move();
  501.                     cursor++;
  502.                 }
  503.             }
  504.         }
  505.     }
  506.     
  507.     close_blanker();
  508.     
  509.     MBS_Quit();
  510.     CloseLibrary( madblankersupportbase );
  511. }
  512.  
  513.  
  514.  
  515.  
  516.